package com.my.structuraltype.flyweight;
/**
 * 享元模式（英语：Flyweight Pattern）是一种软件设计模式。它使用共享物件，用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件；
 * 它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构，当需要使用时再将它们传递给享元。
 * 
 *  享元对象能做到共享的关键是区分内蕴状态和外蕴状态。
 *  一个外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存，并在享元对象被创建之后，在需要使用的时候再传入到享元对象内部。
 *  外蕴状态不可以影响享元对象的内蕴状态。换句话说，它们是相互独立的。
 *  
 *  享元模式在编辑器系统中大量使用。一个文编辑器往往会提供很多种字体，而通常的做法就是将每一个字母做成一个享元对象。享元对象的内蕴状态就是这个字母，而字母在文本中的位置和字体风格等其他信息则是外蕴状态。比如，字母a可以出现在文本的很多地方，虽然这些字母a的位置和字体风格不同，但是所有这些地方使用的都是同一个字母对象。这样一来，字母对象就可以在整个系统中共享。

	  享元模式的优点在于它大幅度地降低内存中对象的数量，但是，它做到这一点所付出的代价也是很高的：
	  享元模式使得系统更加复杂，为了使对象可以共享，需要将一些状态外部化，这使得程序的逻辑复杂化。
	  享元模式将享元享元对象的状态外部化，而读取外部状态使得运行时间稍微变长。
	
	  享元模式可以分为单纯享元模式和复杂享元模式，后者可以认为是前者是组合。
 */
public class Test {

	public static void main(String[] args) {
		Flyweight flyweight1, flyweight2, flyweight3;
		FlyweightFactory ff = new FlyweightFactory();
		flyweight1 = ff.build("in aaa");
		flyweight2 = ff.build("in bbb");
		flyweight3 = ff.build("in aaa");

		flyweight1.func("ext aaa");
		flyweight2.func("ext bbb");
		flyweight3.func("ext ccc");

		ff.checkFlyweight();
	}

}
